#ifndef TEMPLATE_H
#define TEMPLATE_H 1

#include "main.h"
#include "reader.h"
#include "array.h"
#include "dict.h"
#include "request.h"

#define TMPLERR_OK	0
#define TMPLERR_FAILED	1
#define TMPLERR_NOFILES	2

#ifdef ENABLE_DEBUG
# define TMPL_DBG(funcname, tmpl_data_ptr) DD("'%s' -> %s", funcname, (tmpl_data_ptr ? get_string(tmpl_data_ptr->path) : "null"));
#else
# define TMPL_DBG(funcname, tmpl_data_ptr)
#endif
#define TMPL_ATTR "tmpl"
#define TMPL_GET(tmpl_destptr, tmpl_data_ptr, var_reqdata, default_tmpl_str) \
        if ( (tmpl_data_ptr = get_tmpl_ptr_from_attr(var_reqdata->attrs, default_tmpl_str, &tmpl_destptr)) == NULL) { \
          E("[%lu] No template available", var_reqdata->req->req_num); \
        } else { \
          tmpl_request(tmpl_destptr, tmpl_data_ptr, var_reqdata->req); \
        } \
        TMPL_DBG("getTemplate", tmpl_data_ptr)
#define TMPL_SIMPLE(tmpl_destptr, tmpldata, varreqdata, defaultval) \
        const char *attr = NULL; \
        GET_ATTR(varreqdata->attrs, TMPL_ATTR, defaultval, attr) \
        TMPL_GET(tmpl_destptr, tmpldata, varreqdata, attr)
#define TMPL_RESULT(tmpl, data, result) \
        tmpl_parse_result(tmpl, data, result); \
        TMPL_DBG("getResult", data);

typedef struct array tmpl_arr_t;
typedef struct __ncattr__ tmpl_data {
  string_t *path;
  string_t *data;
  void *__unused;
  struct tmpl_data *next;
} tmpl_data_t;

typedef int (*tmpl_cb)(void);
typedef int (*tmpl_setcb)(const tmpl_data_t *, const char *, const char *);
typedef tmpl_data_t * (*tmpl_getptr)(const char *filename);
typedef string_t * (*tmpl_resultcb)(const tmpl_data_t *, string_t **str_ptr);
typedef void (*tmpl_reqcb)(const tmpl_data_t *td, const request_t *req);

typedef struct __ncattr__ tmpl {
  const char *name;
  tmpl_cb preinit_cb;
  tmpl_cb init_cb;
  tmpl_cb free_cb;
  tmpl_cb cleanup_cb;
  tmpl_setcb set_cb;
  tmpl_getptr tmplptr_cb;
  tmpl_resultcb tmplresult_cb;
  tmpl_reqcb tmplreq_cb;
} tmpl_t;

#include "templates.h"

extern const char tmpl_dir[MAXPATHLEN+1];

int
set_template_dir(const char *dir);

tmpl_data_t *
read_template_files(const char *suffix);

void
cleanup_template(tmpl_data_t *data);

void
preinit_templates(void);

void
init_templates_thrd(void);

void
free_templates(void);

void
templates_cleanup_thrd(void);

int
tmpl_set_val(const tmpl_t *tmpl, const tmpl_data_t *tdat, const char *key, const char *value);

int
tmpl_setf_val(const tmpl_t *tmpl, const tmpl_data_t *tdat, const char *key, const char *fmt, ...);

tmpl_data_t *
get_tmpl_ptr(const char *filename, const tmpl_t **tmpl_destptr);

tmpl_data_t *
get_tmpl_ptr_from_attr(dict_t *dict, const char *default_tmpl, const tmpl_t **tmpl_destptr);

string_t *
tmpl_parse_result(const tmpl_t *tmpl, const tmpl_data_t *tdat, string_t **str_ptr);

void
tmpl_request(const tmpl_t *tmpl, const tmpl_data_t *tdat, const request_t *req);

#endif
